#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include "mongoose.h"
#include "cJSON.h"



#if 0

// 客户端 文件下载

// curl -O "http://192.168.182.131:8080/download?filename=dtu.json"

// ...existing code...

static void handle_download_request(struct mg_connection *c, struct http_message *hm) {
    char filename[256] = {0};
    char full_path[512] = {0};
    const char *default_root = "./";

    mg_get_http_var(&hm->query_string, "filename", filename, sizeof(filename));

    if (filename[0] == '\0') {
        mg_printf(c, "HTTP/1.1 400 Bad Request\r\n"
                     "Content-Type: text/plain\r\n"
                     "Content-Length: 25\r\n\r\n"
                     "Filename parameter missing\n");
        c->flags |= MG_F_SEND_AND_CLOSE;
        return;
    }
    if (strstr(filename, "..") != NULL) {
        mg_printf(c, "HTTP/1.1 403 Forbidden\r\n"
                     "Content-Type: text/plain\r\n"
                     "Content-Length: 29\r\n\r\n"
                     "Forbidden: Invalid filename\n");
        c->flags |= MG_F_SEND_AND_CLOSE;
        return;
    }

    snprintf(full_path, sizeof(full_path), "%s/%s", default_root, filename);

    FILE *file = fopen(full_path, "rb");
    if (file == NULL) {
        mg_printf(c, "HTTP/1.1 404 Not Found\r\n"
                     "Content-Type: text/plain\r\n"
                     "Content-Length: 15\r\n\r\n"
                     "File not found\n");
        c->flags |= MG_F_SEND_AND_CLOSE;
        return;
    }

    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    // 构造 extra_headers，注意不要以 \r\n 结尾
    char extra_headers[512];
    snprintf(extra_headers, sizeof(extra_headers),
             "Content-Type: application/octet-stream\r\n"
             "Content-Disposition: attachment; filename=\"%s\"", filename);

    mg_send_head(c, 200, file_size, extra_headers);

    char buffer[8192];
    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
        mg_send(c, buffer, bytes_read);
    }
    fclose(file);

    c->flags |= MG_F_SEND_AND_CLOSE;
}

// ...existing code...

// ...existing code...

// 新增普通请求应答接口
static void handle_hello_request(struct mg_connection *c, struct http_message *hm) {
    const char *reply = "Hello, world!\n";
    mg_printf(c,
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/plain\r\n"
        "Content-Length: %d\r\n\r\n"
        "%s",
        (int)strlen(reply), reply);
    c->flags |= MG_F_SEND_AND_CLOSE;
}

// ...existing code...

static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
    if (ev == MG_EV_HTTP_REQUEST) {
        struct http_message *hm = (struct http_message *) ev_data;

        if (mg_vcmp(&hm->uri, "/download") == 0) {
            handle_download_request(c, hm);
        } else if (mg_vcmp(&hm->uri, "/hello") == 0) {
            handle_hello_request(c, hm);
        } else {
            mg_printf(c, "HTTP/1.1 404 Not Found\r\n"
                         "Content-Type: text/plain\r\n"
                         "Content-Length: 10\r\n\r\n"
                         "Not Found\n");
            c->flags |= MG_F_SEND_AND_CLOSE;
        }
    }
}

// ...existing code...

static struct mg_serve_http_opts s_http_server_opts;

int main(void) {

    struct mg_mgr mgr;

    /* Open listening socket */
    mg_mgr_init(&mgr, NULL);
    struct mg_connection *nc = mg_bind(&mgr, "8080", ev_handler);
    if (nc == NULL)
    {
        return -1;
    }

    printf("Starting RESTful server on port 8080\n");

    mg_set_protocol_http_websocket(nc);
    s_http_server_opts.document_root = "./webserver";
    s_http_server_opts.enable_directory_listing = "yes";
    /* Run event loop until signal is received */

    while (1)
    {
        mg_mgr_poll(&mgr, 1000);
    }

    /* Cleanup */
    mg_mgr_free(&mgr);
    return 0;
}


#else 

// 客户端程序



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "mongoose.h"

// 回调需要访问 done 标志，使用结构体传递
struct http_client_ctx {
    bool *done;
};

static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
    struct http_client_ctx *ctx = (struct http_client_ctx *)c->user_data;
    if (ev == MG_EV_CONNECT) {
        if (*(int *)ev_data != 0) {
            printf("Connection failed!\n");
            if (ctx && ctx->done) *ctx->done = true;
            c->flags |= MG_F_CLOSE_IMMEDIATELY;
        }
    } else if (ev == MG_EV_HTTP_REPLY) {
        struct http_message *hm = (struct http_message *)ev_data;
        printf("HTTP response code: %d\n", hm->resp_code);
        printf("Response body:\n%.*s\n", (int)hm->body.len, hm->body.p);
        if (ctx && ctx->done) *ctx->done = true;
        c->flags |= MG_F_CLOSE_IMMEDIATELY;
    } else if (ev == MG_EV_CLOSE) {
        // 连接关闭
    }
}

int main(void) {
    struct mg_mgr mgr;
    struct mg_connection *c;
    bool done = false;
    struct http_client_ctx ctx;
    ctx.done = &done;

    mg_mgr_init(&mgr, NULL);

    // 使用指定GET接口
    const char *url = "http://112.35.30.26:20001/exchange/device/register?productKey=a1q5OZTEiYV&sn=1211102025090801&secretKey=xaba7c7499570000";
    c = mg_connect_http(&mgr, ev_handler, url, NULL, NULL);
    if (c == NULL) {
        printf("Failed to create connection\n");
        return 1;
    }
    c->user_data = &ctx;

    printf("Requesting: %s\n", url);

    // 事件循环，直到 done 变为 true
    while (!done) {
        mg_mgr_poll(&mgr, 100);
    }

    mg_mgr_free(&mgr);
    return 0;
}

#endif